package com.b2c.common.utils;

import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description: 数字处理工具类
 * pbd add 2018/12/21 10:54
 */
public class NumberUtil {
    /**
     * 生成流水号(钱帮主标识+纳秒数)
     *
     * @return
     */
    public static String createlishuiNo() {
        return "qbz" + System.nanoTime();
    }

    /**
     * 生成PDF(钱帮主标识+纳秒数)
     *
     * @return
     */
    public static String createPdfNo() {
        return "qbzPdf" + System.nanoTime();
    }

    /**
     * long为null处理
     * @param value
     * @return
     */
    public static Long isLongNull(Long value){
        if(StringUtils.isEmpty(value)){
            return 0L;
        }else return value;
    }
    public static Double isDoubleNull(Double value){
        if(StringUtils.isEmpty(value)){
            return 0D;
        }else return value;
    }

    /**
     * 判断当前值是否为整数
     *
     * @param value
     * @return
     */
    public static boolean isInteger(Object value) {
        if (value == null) {
            return false;
        }
        String mstr = value.toString();
        Pattern pattern = Pattern.compile("^-?\\d+{1}");
        return pattern.matcher(mstr).matches();
    }

    /**
     * 判断当前值是否为数字(包括小数)
     *
     * @param value
     * @return
     */
    public static boolean isDigit(Object value) {
        if (value == null) {
            return false;
        }
        String mstr = value.toString();
        Pattern pattern = Pattern.compile("^-?[0-9]*.?[0-9]*{1}");
        return pattern.matcher(mstr).matches();
    }

    /**
     * 取两位小数，并四舍五入
     *
     * @param num
     * @return
     */
    public static double round(double num) {
        return (double) NumberUtil.format(num * 100) / 100;
    }

    /**
     * 将数字格式化输出
     *
     * @param value     需要格式化的值
     * @param precision 精度(小数点后的位数)
     * @return
     */
    public static Double format(Object value, Integer precision) {
        Double number = 0.0;
        if (NumberUtil.isDigit(value)) {
            number = Double.parseDouble(value.toString());
        }
        precision = (precision == null || precision < 0) ? 2 : precision;
        BigDecimal bigDecimal = new BigDecimal(number);
        return bigDecimal.setScale(precision, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 将数字格式化输出(取整数)
     *
     * @param value
     * @return
     */
    public static int format(Object value) {
        if (value == null) {
            return 0;
        }
        return format(value, 0).intValue();
    }

    /**
     * 循环格式化输出
     *
     * @param value     需要格式化的值
     * @param precision 精度(小数点后的位数)
     * @return
     */
    public static BigDecimal format(BigDecimal value, Integer precision) {
        String numStr = value.toString();
        numStr = numStr.substring(numStr.indexOf(".") + 1);
        for (int i = numStr.length(); i >= precision; i--) {
            value = value.setScale(i, RoundingMode.HALF_UP);
        }
        return value;
    }

    /**
     * 将值转成Integer型，如果不是整数，则返回0
     *
     * @param value
     * @param replace 如果为0或者null，替换值
     * @return
     */
    public static Integer parseInteger(Object value, Integer replace) {
        if (!NumberUtil.isInteger(value)) {
            return replace;
        }
        return Integer.parseInt(value.toString());
    }

    /**
     * 将值转成Integer型，如果不是整数，则返回0
     *
     * @param value
     * @return
     */
    public static Integer parseInteger(Object value) {
        return NumberUtil.parseInteger(value, 0);
    }

    /**
     * 将值转成Long型
     *
     * @param value
     * @param replace 如果为0或者null，替换值
     * @return
     */
    public static Long parseLong(Object value, Long replace) {
        if (!NumberUtil.isInteger(value)) {
            return replace;
        }
        return Long.parseLong(value.toString());
    }

    /**
     * 将值转成Long型，如果不是整数，则返回0
     *
     * @param value
     * @return
     */
    public static Long parseLong(Object value) {
        return NumberUtil.parseLong(value, 0L);
    }

    /**
     * 将值转成Double型
     *
     * @param value
     * @param replace replace 如果为0或者null，替换值
     * @return
     */
    public static Double parseDouble(Object value, Double replace) {
        if (!NumberUtil.isDigit(value)) {
            return replace;
        }
        return Double.valueOf(value.toString());
    }

    /**
     * 将值转成Double型
     *
     * @param value
     * @param replace replace 如果为0或者null，替换值
     * @return
     */
    public static BigDecimal parseDecimal(Object value, BigDecimal replace) {
        if (!NumberUtil.isDigit(value)) {
            return replace;
        }
        return new BigDecimal(value.toString());
    }

    /**
     * 将值转成BigDecimal型，如果不是整数，则返回0
     *
     * @param value
     * @return
     */
    public static BigDecimal parseDecimal(Object value) {
        return NumberUtil.parseDecimal(value, new BigDecimal(0));
    }

    /**
     * 将值转成Double型，如果不是整数，则返回0
     *
     * @param value
     * @return
     */
    public static Double parseDouble(Object value) {
        return NumberUtil.parseDouble(value, 0.0);
    }

    /**
     * 将char型数据转成字节数组
     *
     * @param value
     * @return
     */
    public static byte[] toBytes(char value) {
        byte[] bt = new byte[2];
        for (int i = 0; i < bt.length; i++) {
            bt[i] = (byte) (value >>> (i * 8));
        }
        return bt;
    }

    /**
     * 将short型数据转成字节数组
     *
     * @param value
     * @return
     */
    public static byte[] toBytes(short value) {
        byte[] bt = new byte[2];
        for (int i = 0; i < bt.length; i++) {
            bt[i] = (byte) (value >>> (i * 8));
        }
        return bt;
    }

    /**
     * 将int型数据转成字节数组
     *
     * @param value
     * @return
     */
    public static byte[] toBytes(int value) {
        byte[] bt = new byte[4];
        for (int i = 0; i < bt.length; i++) {
            bt[i] = (byte) (value >>> (i * 8));
        }
        return bt;
    }

    /**
     * 将long型数据转成字节数组
     *
     * @param value
     * @return
     */
    public static byte[] toBytes(long value) {
        byte[] bt = new byte[8];
        for (int i = 0; i < bt.length; i++) {
            bt[i] = (byte) (value >>> (i * 8));
        }
        return bt;
    }

    /**
     * 将short型数据插入到指定索引的字节数组中
     *
     * @param index  索引
     * @param values 字节数组
     * @param value  需要插入的值
     */
    public static void insert(int index, byte[] values, short value) {
        byte[] bt = NumberUtil.toBytes(value);
        System.arraycopy(bt, 0, values, index, 2);
    }

    /**
     * 将int型数据插入到指定索引的字节数组中
     *
     * @param index  索引
     * @param values 字节数组
     * @param value  需要插入的值
     */
    public static void insert(int index, byte[] values, int value) {
        byte[] bt = NumberUtil.toBytes(value);
        System.arraycopy(bt, 0, values, index, 4);
    }

    /**
     * 将long型数据插入到指定索引的字节数组中
     *
     * @param index  索引
     * @param values 字节数组
     * @param value  需要插入的值
     */
    public static void insert(int index, byte[] values, long value) {
        byte[] bt = NumberUtil.toBytes(value);
        System.arraycopy(bt, 0, values, index, 8);
    }

    /**
     * 将字节转换成整型
     *
     * @param value 字节类型值
     * @return
     */
    public static int byteToInt(byte value) {
        if (value < 0) {
            return value + 256;
        }
        return value;
    }

    /**
     * 生成两位小数的区间随机数
     *
     * @param max 范围最大值
     * @param min 范围最小值
     * @return
     * @author Sivan
     */
    public static double random(double min, double max) {
        BigDecimal db = new BigDecimal(Math.random() * (max - min) + min);
        return db.setScale(2, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * @param min
     * @param max
     * @return double
     * @Description: 随机产生指定范围内的随机数(1位小数)
     * @date 2016年9月21日 上午10:09:38
     * @author pbd
     */
    public static double randomDouble(double min, double max) {
        BigDecimal db = new BigDecimal(Math.random() * (max - min) + min);
        return db.setScale(1, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * @param min
     * @param max
     * @return double
     * @Description: 随机产生指定范围内的随机数(2位小数)
     * @date 2016年9月21日 上午10:09:38
     * @author pbd
     */
    public static double randomDouble2(double min, double max) {
        BigDecimal db = new BigDecimal(Math.random() * (max - min) + min);
        return db.setScale(2, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * @param min
     * @param max
     * @return double
     * @Description: 随机产生指定范围内的随机数(包含边界值 : 最小最大值)
     * @date 2016年9月21日 上午10:09:38
     * @author pbd
     */
    public static int randomInt(double min, double max) {
        BigDecimal db = new BigDecimal(Math.random() * (max - min + 1) + min);
        return db.intValue();
    }

    /**
     * @return Set<Integer>
     * @Description:双色球红球号码
     * @date 2016年12月6日 下午6:00:56
     * @author pbd
     */
    public static Set<Integer> randomSet() {
        Random ran = new Random();
        Set<Integer> set = new TreeSet<>();
        while (true) {
            int a = ran.nextInt(33) + 1;
            set.add(a);
            if (set.size() > 5) {
                System.out.print(set);
                break;
            }
        }
        return set;
    }

    /**
     * @return int
     * @Description:随机双色球id
     * @date 2016年11月23日 上午10:12:43
     * @author pbd
     */
    public static int randomSsqId(int a, int b) {
        int[] array = {a, b};
        return array[new Random().nextInt(2)];
    }

    /**
     * 保留2位小数
     *
     * @param number
     * @return
     */
    public static String getReating(Double number) {
        //获取格式化对象
        NumberFormat nt = NumberFormat.getPercentInstance();
        //设置百分数精确度2即保留两位小数
        nt.setMinimumFractionDigits(2);
        //最后格式化并输出
        return nt.format(number);
    }

    /**
     * 格式化数据，不保留小数
     *
     * @return
     */
    public static BigDecimal formatAmount(Object obj) {
        BigDecimal value = null;
        if (obj == null)
            return new BigDecimal(0);
        if (obj instanceof BigDecimal) {
            value = (BigDecimal) obj;
        } else if (obj instanceof String) {
            value = new BigDecimal(obj.toString());
        } else if (obj instanceof BigInteger) {
            value = new BigDecimal((BigInteger) obj);
        } else if (obj instanceof Number) {
            value = new BigDecimal(((Number) obj).doubleValue());
        }
        return value.setScale(0,RoundingMode.HALF_UP).setScale(2);
    }

    /**
     * 格式化数据，去掉小数点后无意义的0
     *
     * @param number
     * @return
     */
    public static String formatNumber(BigDecimal number) {
        DecimalFormat AMOUNT_SPLIT_FORMAT = new DecimalFormat("0.##");
        if (number == null) {
            return "";
        }
        return AMOUNT_SPLIT_FORMAT.format(number);
    }

    public static String formatAmt(String amount) {
        DecimalFormat AMOUNT_FORMAT = new DecimalFormat("#####0.00");
        return AMOUNT_FORMAT.format(BigDecimal.valueOf(Long.valueOf(amount)).divide(new BigDecimal(100)));
    }

    public static String getMoney(BigDecimal amt, BigDecimal rate) {
        BigDecimal money = amt.setScale(8, RoundingMode.HALF_UP).multiply(rate);
        return money.setScale(0, RoundingMode.HALF_UP).toString();
    }

//     public static void main(String[] args) {
// /*		String red="";
// 		String blue="";
// 		ArrayList<Integer> arr = new ArrayList<Integer>();
// 		for(int i=0;i<=5;i++){
// 			arr.add(randomInt(1,33));
// 		}
// 		StringBuffer str = new StringBuffer();
// 		 for (int i : arr) {
// 			 str.append(i).append(" ");
// 	        }
// 		 str.deleteCharAt(str.length()-1);
// 	     red=str.toString();
// 	     blue=String.valueOf(randomInt(1,16));
// 	     System.out.println(red+" "+blue);*/
// 		/*for(int i=0;i<=100;i++){
// 			System.out.println(randomInt(1,16));
// 		}*/
//         //System.out.println(formatAmt("100101"));
//         //System.out.println(NumberUtil.getBirAgeSex("52242619811105565X"));

//         System.out.println(new BigDecimal(1 * 100).multiply(new BigDecimal(0.005)).setScale(2, RoundingMode.HALF_UP));
//         System.out.println(formatAmount(new BigDecimal(1000000.99)));
//     }

    /**
     * @param IdNO
     * @return pbd add 2018年6月15日 下午5:46:12
     * @Description: 根据身份证号获得年龄
     */
    public static int IdNOToAge(String IdNO) {
        int leh = IdNO.length();
        String dates = "";
        if (leh == 18) {
            int se = Integer.valueOf(IdNO.substring(leh - 1)) % 2;
            dates = IdNO.substring(6, 10);
            SimpleDateFormat df = new SimpleDateFormat("yyyy");
            String year = df.format(new Date());
            int u = Integer.parseInt(year) - Integer.parseInt(dates);
            return u;
        } else {
            dates = IdNO.substring(6, 8);
            return Integer.parseInt(dates);
        }

    }

    /**
     * @param certificateNo
     * @return pbd add 2018年6月27日 上午9:48:22
     * @Description: 根据身份证号获得年龄
     */
    public static int getBirAgeSex(String certificateNo) {
/*	   if(certificateNo.length() != 15 && certificateNo.length() != 18){
		   return 30;
	   }*/
        String age = "";
        int year = Calendar.getInstance().get(Calendar.YEAR);
        char[] number = certificateNo.toCharArray();
        boolean flag = true;
        if (number.length == 15) {
            for (int x = 0; x < number.length; x++) {
                flag = Character.isDigit(number[x]);
            }
        } else if (number.length == 18) {
            for (int x = 0; x < number.length - 1; x++) {
                flag = Character.isDigit(number[x]);
            }
        }
        if (flag && certificateNo.length() == 15) {
            age = (year - Integer.parseInt("19" + certificateNo.substring(6, 8))) + "";
        } else if (flag && certificateNo.length() == 18) {
            age = (year - Integer.parseInt(certificateNo.substring(6, 10))) + "";
        }
        return Integer.parseInt(age);
    }

    /**
     * @param mobiles
     * @return boolean
     * @Description: check手机号
     * @date 2017年8月18日 下午5:44:11
     * @author pbd
     */
    public static boolean checkPhone(String mobiles) {
        boolean flag = false;
        try {
            Pattern p = Pattern.compile("^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\\d{8}$");
            Matcher m = p.matcher(mobiles.trim());
            flag = m.matches();
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    public static BigDecimal getBigDecimal() {
        BigDecimal syhb = new BigDecimal(8);
        BigDecimal hbAmount = new BigDecimal(5);
        if (syhb.compareTo(hbAmount) > 0 && hbAmount.compareTo(new BigDecimal(0)) > 0) {
            System.out.println(syhb.subtract(hbAmount));
        }
        //剩余红包小于可得红包发放剩余红包
        if ((syhb.compareTo(hbAmount) <= 0 || hbAmount.compareTo(syhb) >= 0) && hbAmount.compareTo(new BigDecimal(0)) > 0) {
            hbAmount = syhb;
        }
        return hbAmount;
    }
}
